/*function JayPromise(fn) {
  this.doneCallback = null  //需要一个成功时的回调

  fn(this.resolve)
}

JayPromise.prototype.then = function (done) {
  this.doneCallback = done
}

JayPromise.prototype.resolve = function () {
  this.doneCallback && this.doneCallback()
}*/

/**
 * 自行实现 Promise 对象。
 * 参考网址：https://blog.csdn.net/u014775861/article/details/78030508
 */
class JayPromise {
  constructor(executor) {
    this._promiseStatus = Promise.PENDING;
    this._promiseValue;

    // 传入构造器的executor为函数，并且在构造时就会执行
    this._execute(executor);
  }

  /**
   * 在构造时就会执行。
   * executor 中传入 resolve 和 reject 参数，这两个参数都是函数，用于改变改变 _promiseStatus和 _promiseValue 的值。
   * 内部做了捕获异常的操作。
   * @param executor
   * @private
   */
  _execute(executor) {
    if (typeof executor !=== 'function') {
      throw new Error(`Promise resolver ${executor} is not a function`)
    }

    try {
      executor(
        data => {
          this._promiseStatus = JayPromise.FULFILLED
          this._promiseValue = data
        },
        data => {
          this._promiseStatus = JayPromise.REJECTED
          this._promiseValue = data
        }
      )
    } catch (e) {
      this._promiseStatus = JayPromise.REJECTED
      this._promiseValue = e
    }
  }

  /**
   * 一定要注意到: then 方法中的回调是异步执行的，表示该回调是插入事件队列末尾，在当前的同步任务结束之后，下次事件循环开始时执行队列中的任务。
   *
   * then 方法中的难点就是处理异步,其中一个方案是通过 setInterval来监听GPromise 对象的状态改变，一旦改变则执行相应then 中相应的
   * 回调函数(onfulfilled和onrejected),这样回调函数就能够插入事件队列末尾，异步执行，实验证明可行，这种方案是最直观也最容易理解的。
   *
   * then 方法的返回值是一个新的 GPromise 对象，并且这个对象的状态和 then 中的回调返回值相关，回调指代传入的 onfulfilled 和 rejected。
   *    1. 如果 then 中的回调抛出了错误，返回的 GPromise 的 _promiseStatus 赋值为’rejected’， _promiseValue赋值为抛出的错误对象。
   *    2. 如果回调返回了一个非 GPromise 对象， then返回的 GPromise 的 _promiseStatus 赋值为’resolved’， _promiseValue赋值为回调的返回值。
   *    3. 如果回调返回了一个 GPromise 对象，then返回的GPromise对象 的_promiseStatus和 _promiseValue 和其保持同步，
   *       也就是 then 返回的GPromise记录了回调返回的状态和值，不是直接返回回调的返回值。
   *
   * @param onFulfilled
   * @param onRejected
   */
  then(onFulfilled, onRejected) {
    
  }
}

JayPromise.PENDING = 'pending'
JayPromise.FULFILLED= 'resolved'
JayPromise.REJECTED= 'rejected'